package controllers

import (
	"crmObject/models"
	"crmObject/util"
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/gomodule/redigo/redis"
	"golang.org/x/crypto/bcrypt"
)

type LoginController struct {
	beego.Controller
}
type LoginRequest struct {
	Uname string `json:"uname"`
	Upwd  string `json:"upwd"`
}
type LoginResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

func (c *LoginController) ShowLogin() {
	c.TplName = "login.html"
}

// TODO 使用前端cookie或者sesion来完成快速登陆,不用每次都访问后端数据库

func (c *LoginController) HandelLogin() {
	var userHtml models.Users
	var users models.Users
	//序列化获取json数据
	err := json.Unmarshal(c.Ctx.Input.RequestBody, &userHtml)
	if err != nil {
		fmt.Println(err)
		errCode := 500
		newError := util.NewError(errCode)
		c.Data["json"] = LoginResponse{Code: newError.Code, Message: newError.Message}
		c.ServeJSON()
		return
	}
	if userHtml.Username == "" || userHtml.Username == "" {
		fmt.Println(err)
		errCode := 505
		newError := util.NewError(errCode)
		c.Data["json"] = LoginResponse{Code: newError.Code, Message: newError.Message}
		c.ServeJSON()
		return
	}
	newOrm := orm.NewOrm()
	err = newOrm.QueryTable("users").Filter("username", userHtml.Username).One(&users)
	//查询不到数据说明没有数据库中没有这个账号
	if err != nil {
		fmt.Println(err)
		errCode := 508
		newError := util.NewError(errCode)
		c.Data["json"] = LoginResponse{Code: newError.Code, Message: newError.Message}
		c.ServeJSON()
		return
	}
	//比较密码
	err = bcrypt.CompareHashAndPassword([]byte(users.Password), []byte(userHtml.Password))

	if err != nil {
		fmt.Println(err)
		errCode := 500
		newError := util.NewError(errCode)
		c.Data["json"] = LoginResponse{Code: newError.Code, Message: newError.Message}
		c.ServeJSON()
		return
	}

	//-----存入redis中
	//结构体转为json类型
	marshal, err := json.Marshal(&users)
	if err != nil {
		fmt.Println(err)
		errCode := 500
		newError := util.NewError(errCode)
		c.Data["json"] = LoginResponse{Code: newError.Code, Message: newError.Message}
		c.ServeJSON()
		return
	}
	var usersJson = string(marshal)
	//获取redis连接
	redis := util.RedisPool.Get()
	//设定时间为一个小时
	_, err = redis.Do("SET", util.USERS, usersJson, "EX", 3600)
	if err != nil {
		fmt.Println(err)
		errCode := 500
		newError := util.NewError(errCode)
		c.Data["json"] = LoginResponse{Code: newError.Code, Message: newError.Message}
		c.ServeJSON()
		return
	}
	//TODO 做判断如果有就没必要在进行将他覆盖
	//c.Data["json"] = LoginResponse{Success: true, Message: "登陆成功"}
	//TODO 多用户同时操作:每个用户生成的session和cookie不用关
	//设置cookie
	//c.Ctx.SetCookie("users", strconv.Itoa(users.UserID))
	//将user对象存入session

	//不需要手动关闭连接,连接池会进行自我管理
	//defer models.RedisPool.Close()
	//c.SetSession("users", users)
	//然后调用ServeJSON()进行渲染，就可以把数据进行JSON序列化输出。
	//判断身份
	if users.Status == "用户" {
		c.Data["json"] = LoginResponse{Code: 200, Message: "欢迎用户登陆"}
	} else {
		c.Data["json"] = LoginResponse{Code: 200, Message: "欢迎管理员登陆"}
	}
	c.ServeJSON()
}

//退出登陆

func (c *LoginController) QuitLogin() {
	//  退出的同时删除cookie和session
	//c.DelSession("users")
	//第一个参数是Cookie的key值，第二个参数任意值，第三个参数把Cookie的值设置为小于0，就马上失效。
	//c.Ctx.SetCookie("users", "删除", -1)
	//删除redis中的缓存
	conn := util.RedisPool.Get()
	_, err := conn.Do("DEL", util.USERS)
	if err != nil {
		fmt.Println(err)
		errCode := 500
		newError := util.NewError(errCode)
		c.Data["error"] = newError
		c.TplName = "error.html"
	}
	//TODO 指定一些路径使用拦截器来完成,判断
	//TODO 进行判断是否还有数据
	//c.Data["json"] = LoginResponse{Success: true, Message: "退出成功"}
	defer conn.Close()
	c.TplName = "login.html"
}

// 密码修改
//func (c *LoginController) ToUpdatePassword() {
//
//	//TODO  可以使用redis判断旧密码是否合法
//	//从session获取值返回给前端
//	//sesssion的东西会存在哪里
//	//TODO 用户详情页面
//	//session := c.GetSession(c.Ctx.GetCookie("users"))
//	//类型断言
//	//users := session.(models.Users)
//	//c.Data["json"] = map[string]interface{}{"username": users.Username, "aaa": 123}
//	oldPassword := c.GetString("oldPassword")
//	newPassword := c.GetString("newPassword")
//	if oldPassword == "" || newPassword == "" {
//		c.Data["json"] = LoginResponse{Success: false, Message: "密码为空"}
//		c.ServeJSON()
//		return
//	}
//	//旧密码和新密码不能是相同的
//	if newPassword == oldPassword {
//		c.Data["json"] = LoginResponse{Success: false, Message: "旧密码和新密码不能相同"}
//		//TODO 让他返回到上一页面
//		c.ServeJSON()
//		return
//	}
//	//TODO 防止前端业务太频繁,这里可以使用redis或者session先进行存储修改后的数据,写一个定时器,到了晚上在统一来处理这些操作
//	//session中取数据
//	usersSession := c.GetSession("users")
//	//断言类型转换  session中取出来的不是users类型,需要转换类型
//	users := usersSession.(models.Users)
//	if oldPassword != users.Password {
//		c.Data["json"] = LoginResponse{Success: false, Message: "旧密码错误"}
//		c.ServeJSON()
//		return
//	}
//	users.Password = newPassword
//	newOrm := orm.NewOrm()
//	//修改数据库中的数据
//	_, err := newOrm.Update(&users, "password")
//	if err != nil {
//		c.Data["json"] = LoginResponse{Success: false, Message: "系统出错了,请重试"}
//		c.ServeJSON()
//		return
//	}
//	c.Data["json"] = LoginResponse{Success: true, Message: "密码修改完成"}
//	c.ServeJSON()
//}

func IsUserLoggedIn() bool {
	conn := util.RedisPool.Get()
	// 从 Redis 中读取 JSON 字符串
	userJSON, err := redis.String(conn.Do("GET", util.USERS))
	if err != nil {
		fmt.Println(err)
	}
	// 将 JSON 字符串反序列化为结构体
	err = json.Unmarshal([]byte(userJSON), &user)

	// 判断用户名是否存在
	if user.Username == "" {
		return false
	}
	defer conn.Close()
	return true
}
